package ProtoSimulator;
/*
 * ProtoSimulator.java
 *
 * Created on November 30, 2005, 9:41 PM
 */

/**
 *
 * @author  jjmb
 */

import java.lang.Thread.State;
import java.net.*;
import java.io.*;
import java.util.*;

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;

import Clients.*;

public class Manager {
    private static final String CLASS_NAME = Manager.class.getName();
    public static final Logger logger = Logger.getLogger(CLASS_NAME);
    
    private static String propertiesFile = "/etc/ProtoSimulator.properties";
    private static String log4jPropertiesFile = "/etc/Simulator_log4j.properties";
    private static String smtpPropertiesFile = "/etc/Simulator_smtp.properties";
    private static Properties properties = new Properties();
    private static Properties smtpProperties = new Properties();    
    private static String Url = "http://localhost";
    private static int maxRequests = 5;
    private static int maxIterations = 1;
    private static boolean debug = false;
    private static String protocol = "http";
    // private static Http simulator = null;
    // private static List clientList = null;
    private static String smtpBody = null;
    private static String smtpAttachment = null;
    private static String smtpTo = null;
	private static HashMap clientState = new HashMap();
	private static Status status = new Status();
	private static NotificationHandler nh = null;
	private static Notification n = new Notification();
    
    public long elapsedIterationTimer = 0;
    
    /** Creates a new instance of ProtoSimulator */
    public Manager() {
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        URL url = null;
        String webdata = null;
        int requestCount = 0;
        int iterationCount = 0;
        long requestTime = 0;
        long iterationTime = 0;
        long totalRequestTime = 0;
        long totalIterationTime = 0;
        int totalRequests = 0;
        int argslen = args.length;
        int argscount = 0;
        boolean complete = false;
        boolean help = false;
        
        System.setProperty("java.net.preferIPv6Addresses", "true");
        
        System.out.println("Number of arguments to process, " + argslen);
        while(argscount < argslen) {
            if(args[argscount].equalsIgnoreCase("--protocol")) {
                protocol = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--log4j")) {
                log4jPropertiesFile = args[argscount+1].toString();
            }                        
            if(args[argscount].equalsIgnoreCase("--url")) {
                Url = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--debug")) {
                debug = true;
            }
            if(args[argscount].equalsIgnoreCase("--requests")) {
                maxRequests = Integer.parseInt(args[argscount+1].toString());
            }
            if(args[argscount].equalsIgnoreCase("--iterations")) {
            	maxIterations = Integer.parseInt(args[argscount+1].toString());
            }
            if(args[argscount].equalsIgnoreCase("--properties")) {
            	propertiesFile = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--smtp_properties")) {
            	smtpPropertiesFile = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--smtp_body")) {
            	smtpBody = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--smtp_attachment")) {
            	smtpAttachment = args[argscount+1].toString();
            }  
            if(args[argscount].equalsIgnoreCase("--smtp_to")) {
            	smtpTo = args[argscount+1].toString();
            }
            if(args[argscount].equalsIgnoreCase("--help")) {
            	help = true;
            }                  
            argscount++;
        }
        
        // Command line argument processing
        if((help) || (protocol.isEmpty())) {
            System.out.println("Invalid arguments, exiting");
            System.out.println("Usage: [--protocol] --url --requests --iterations --debug --properties --log4j --smtp_attachment --smtp_to --smtp_properties --smtp_body");
            System.exit(-1);        	
        }
        
        // Properties file processing
        try {
            properties.load(new FileInputStream(propertiesFile));
        } 
        catch (IOException e) {
        	System.out.println("Could not process specified properties file ("+propertiesFile+"), exiting");
            System.exit(-1);
        }
        
        // SmtpProperties file processing, if using SMTP
        try {
        	smtpProperties.load(new FileInputStream(smtpPropertiesFile));
        	if(smtpBody != null) {
        		smtpProperties.setProperty("smtp_body", smtpBody);
        	}
        	if(smtpAttachment != null) {
        		smtpProperties.setProperty("smtp_attachment", smtpAttachment);
        	}
        	if(smtpTo != null) {
        		smtpProperties.setProperty("smtp_to", smtpTo);
        	}
        } 
        catch (IOException e) {
        	System.out.println("Could not process specified properties file ("+smtpPropertiesFile+"), exiting");
            System.exit(-1);
        }        
        
        if(debug) {
            File f = new File(log4jPropertiesFile);
            if((f.exists()) && (f.canRead())) {
                PropertyConfigurator.configureAndWatch(log4jPropertiesFile);
            }
            else {
                System.out.println("Could not read log4j properties file, using basic configuration");
                BasicConfigurator.configure();
            }
        }
        
        logger.info("****************************************");
        logger.info("Protocol = " + protocol.toString());
        logger.info("Url = " + Url);
        logger.info("Maximum Requests = " + maxRequests);
        logger.info("Maximum Iterations = " + maxIterations);
        logger.info("Log4j Properties File = " + log4jPropertiesFile);
        logger.info("Properties File = " + propertiesFile);
        logger.info("SMTP Properties File = " + smtpPropertiesFile);       
        logger.info("****************************************");

        // Constructing NotificationHandler
        nh = new NotificationHandler(n, properties);
        
        // Starting NotificationHandler thread
        /** must fix notification handling **/
        // nh.start();

        // Setting maximum iterations in Status object
        status.setIterationMaximum(maxIterations);
        
        // Starting all requested simulations
        long i0 = System.currentTimeMillis();
        while(iterationCount < maxIterations) {
            if(protocol.equalsIgnoreCase("http")) {
                Http simulator = new Http(status, Url, maxRequests, n);
                simulator.start();
            } else if(protocol.equalsIgnoreCase("smtp")) {
            	Smtp simulator = new Smtp(status, smtpProperties, maxRequests, n);
            	simulator.start();
    		}
            else {
                logger.fatal("Invalid protocol, exiting");
                System.exit(-1);
            }
            logger.trace("Active threads, " + Thread.activeCount());
            iterationCount++;
        }
        
        /**
        totalIterationTime = status.getElapsedTime();
        logger.info("Total number of requests, " + (maxRequests*maxIterations) + " took " + totalIterationTime + "ms");
   		**/
   
        for(;;) {
            if(status.isComplete()) {
            	long i1 = System.currentTimeMillis();
            	logger.info("Elapsed time = " + (i1 - i0) + "ms, for Url = " + Url.toString());
            	
                // Joining NotificationHandler thread
            	if(n.isComplete()) {
                    try {
                    	logger.info("Joining Notification Handler thread...");
                    	nh.join(250);
                    }
                    catch(Exception e) {
                    	logger.fatal(e);
                    }
                	
                	break;
            	}
            }
        }
    }
}
